Add a fake STEPPER function that is used for drawing scrollbar steppers,
authorOwen Taylor <otaylor@redhat.com>
Sun, 21 Apr 2002 19:00:52 +0000 (19:00 +0000)
committerOwen Taylor <otaylor@src.gnome.org>
Sun, 21 Apr 2002 19:00:52 +0000 (19:00 +0000)
Sun Apr 21 14:10:04 2002  Owen Taylor  <otaylor@redhat.com>

        * pixbuf-rc-style.c pixbuf.h pixbuf-draw.c: Add a fake STEPPER
        function that is used for drawing scrollbar steppers,
        so that themes that want to draw the button and arrow
        separately can override the default handling.

        * pixbuf-draw.c: Remove draw_polygon() since it was
        just a cut-and-paste of the default one. Remove
        some unused code.

modules/engines/pixbuf/ChangeLog
modules/engines/pixbuf/pixbuf-draw.c
modules/engines/pixbuf/pixbuf-rc-style.c
modules/engines/pixbuf/pixbuf.h

index 3bb0f8aef1da5d7e3e1ab11974f4264017301d27..d6b717ba8a9dfa5e640c534b4d5f8f27ed75a963 100644 (file)
@@ -1,3 +1,14 @@
+Sun Apr 21 14:10:04 2002  Owen Taylor  <otaylor@redhat.com>
+
+       * pixbuf-rc-style.c pixbuf.h pixbuf-draw.c: Add a fake STEPPER
+       function that is used for drawing scrollbar steppers,
+       so that themes that want to draw the button and arrow
+       separately can override the default handling.
+
+       * pixbuf-draw.c: Remove draw_polygon() since it was
+       just a cut-and-paste of the default one. Remove
+       some unused code.
+
 2002-03-07  James Henstridge  <james@daa.com.au>
 
        * Makefile.am (libpixmap_la_LIBADD): link pixbuf engine against
index 2fe5bc64127efafcd84346fed28dc1f31357653e..9aef0ea7876a5a5a4cf9c4532141f697f301d5cb 100644 (file)
@@ -421,84 +421,48 @@ draw_shadow(GtkStyle     *style,
                               x, y, width, height);
 }
 
+/* This function makes up for some brokeness in gtkrange.c
+ * where we never get the full arrow of the stepper button
+ * and the type of button in a single drawing function.
+ *
+ * It doesn't work correctly when the scrollbar is squished
+ * to the point we don't have room for full-sized steppers.
+ */
 static void
-draw_polygon(GtkStyle * style,
-            GdkWindow * window,
-            GtkStateType state,
-            GtkShadowType shadow,
-            GdkRectangle * area,
-            GtkWidget * widget,
-            const gchar *detail,
-            GdkPoint * points,
-            gint npoints,
-            gint fill)
+reverse_engineer_stepper_box (GtkWidget    *range,
+                             GtkArrowType  arrow_type,
+                             gint         *x,
+                             gint         *y,
+                             gint         *width,
+                             gint         *height)
 {
-#ifndef M_PI
-#define M_PI    3.14159265358979323846
-#endif /* M_PI */
-#ifndef M_PI_4
-#define M_PI_4  0.78539816339744830962
-#endif /* M_PI_4 */
-
-  static const gdouble pi_over_4 = M_PI_4;
-  static const gdouble pi_3_over_4 = M_PI_4 * 3;
-
-  GdkGC              *gc3;
-  GdkGC              *gc4;
-  gdouble             angle;
-  gint                i;
-
-  g_return_if_fail(style != NULL);
-  g_return_if_fail(window != NULL);
-  g_return_if_fail(points != NULL);
-
-  switch (shadow)
-    {
-    case GTK_SHADOW_IN:
-      gc3 = style->light_gc[state];
-      gc4 = style->black_gc;
-      break;
-    case GTK_SHADOW_OUT:
-      gc3 = style->black_gc;
-      gc4 = style->light_gc[state];
-      break;
-    default:
-      return;
-    }
-
-  if (area)
+  gint slider_width = 14, stepper_size = 14;
+  gint box_width;
+  gint box_height;
+  
+  if (range)
     {
-      gdk_gc_set_clip_rectangle(gc3, area);
-      gdk_gc_set_clip_rectangle(gc4, area);
+      gtk_widget_style_get (range,
+                           "slider_width", &slider_width,
+                           "stepper_size", &stepper_size,
+                           NULL);
     }
-  if (fill)
-    gdk_draw_polygon(window, style->bg_gc[state], TRUE, points, npoints);
-
-  npoints--;
-
-  for (i = 0; i < npoints; i++)
+       
+  if (arrow_type == GTK_ARROW_UP || arrow_type == GTK_ARROW_DOWN)
     {
-      if ((points[i].x == points[i + 1].x) &&
-         (points[i].y == points[i + 1].y))
-       angle = 0;
-      else
-       angle = atan2(points[i + 1].y - points[i].y,
-                     points[i + 1].x - points[i].x);
-
-      if ((angle > -pi_3_over_4) && (angle < pi_over_4))
-       gdk_draw_line(window, gc3,
-                     points[i].x, points[i].y,
-                     points[i + 1].x, points[i + 1].y);
-      else
-       gdk_draw_line(window, gc4,
-                     points[i].x, points[i].y,
-                     points[i + 1].x, points[i + 1].y);
+      box_width = slider_width;
+      box_height = stepper_size;
     }
-  if (area)
+  else
     {
-      gdk_gc_set_clip_rectangle(gc3, NULL);
-      gdk_gc_set_clip_rectangle(gc4, NULL);
+      box_width = stepper_size;
+      box_height = slider_width;
     }
+
+  *x = *x - (box_width - *width) / 2;
+  *y = *y - (box_height - *height) / 2;
+  *width = box_width;
+  *height = box_height;
 }
 
 static void
@@ -521,6 +485,57 @@ draw_arrow (GtkStyle     *style,
   g_return_if_fail(style != NULL);
   g_return_if_fail(window != NULL);
 
+  if (strcmp (detail, "hscrollbar") == 0 || strcmp (detail, "vscrollbar") == 0)
+    {
+      /* This is a hack to work around the fact that scrollbar steppers are drawn
+       * as a box + arrow, so we never have
+       *
+       *   The full bounding box of the scrollbar 
+       *   The arrow direction
+       *
+       * At the same time. We simulate an extra paint function, "STEPPER", by doing
+       * nothing for the box, and then here, reverse engineering the box that
+       * was passed to draw box and using that
+       */
+      gint box_x = x;
+      gint box_y = y;
+      gint box_width = width;
+      gint box_height = height;
+
+      reverse_engineer_stepper_box (widget, arrow_direction,
+                                   &box_x, &box_y, &box_width, &box_height);
+
+      match_data.function = TOKEN_D_STEPPER;
+      match_data.detail = (gchar *)detail;
+      match_data.flags = (THEME_MATCH_SHADOW | 
+                         THEME_MATCH_STATE | 
+                         THEME_MATCH_ARROW_DIRECTION);
+      match_data.shadow = shadow;
+      match_data.state = state;
+      match_data.arrow_direction = arrow_direction;
+      
+      if (draw_simple_image (style, window, area, widget, &match_data, TRUE, TRUE,
+                            box_x, box_y, box_width, box_height))
+       {
+         /* The theme included stepper images, we're done */
+         return;
+       }
+
+      /* Otherwise, draw the full box, and fall through to draw the arrow
+       */
+      match_data.function = TOKEN_D_BOX;
+      match_data.detail = (gchar *)detail;
+      match_data.flags = THEME_MATCH_SHADOW | THEME_MATCH_STATE;
+      match_data.shadow = shadow;
+      match_data.state = state;
+      
+      if (!draw_simple_image (style, window, area, widget, &match_data, TRUE, TRUE,
+                             box_x, box_y, box_width, box_height))
+       parent_class->draw_box (style, window, state, shadow, area, widget, detail,
+                               box_x, box_y, box_width, box_height);
+    }
+
+
   match_data.function = TOKEN_D_ARROW;
   match_data.detail = (gchar *)detail;
   match_data.flags = (THEME_MATCH_SHADOW | 
@@ -565,37 +580,7 @@ draw_diamond (GtkStyle     *style,
     parent_class->draw_diamond (style, window, state, shadow, area, widget, detail,
                                x, y, width, height);
 }
-/*
-static void
-draw_oval (GtkStyle     *style,
-          GdkWindow    *window,
-          GtkStateType  state,
-          GtkShadowType shadow,
-          GdkRectangle *area,
-          GtkWidget    *widget,
-          const gchar  *detail,
-          gint          x,
-          gint          y,
-          gint          width,
-          gint          height)
-{
-  ThemeMatchData match_data;
-  
-  g_return_if_fail(style != NULL);
-  g_return_if_fail(window != NULL);
-
-  match_data.function = TOKEN_D_OVAL;
-  match_data.detail = (gchar *)detail;
-  match_data.flags = THEME_MATCH_SHADOW | THEME_MATCH_STATE;
-  match_data.shadow = shadow;
-  match_data.state = state;
 
-  if (!draw_simple_image (style, window, area, widget, &match_data, TRUE, TRUE,
-                         x, y, width, height))
-    parent_class->draw_oval (style, window, state, shadow, area, widget, detail,
-                            x, y, width, height);
-}
-*/
 static void
 draw_string (GtkStyle * style,
             GdkWindow * window,
@@ -652,6 +637,12 @@ draw_box (GtkStyle     *style,
   g_return_if_fail(style != NULL);
   g_return_if_fail(window != NULL);
 
+  if (strcmp (detail, "hscrollbar") == 0 || strcmp (detail, "vscrollbar") == 0)
+    {
+      /* We handle this in draw_arrow */
+      return;
+    }
+
   match_data.function = TOKEN_D_BOX;
   match_data.detail = (gchar *)detail;
   match_data.flags = THEME_MATCH_SHADOW | THEME_MATCH_STATE;
@@ -755,69 +746,6 @@ draw_option (GtkStyle      *style,
                               x, y, width, height);
 }
 
-/*
-static void
-draw_cross (GtkStyle     *style,
-           GdkWindow    *window,
-           GtkStateType  state,
-           GtkShadowType shadow,
-           GdkRectangle *area,
-           GtkWidget    *widget,
-           const gchar  *detail,
-           gint          x,
-           gint          y,
-           gint          width,
-           gint          height)
-{
-  ThemeMatchData match_data;
-  
-  g_return_if_fail(style != NULL);
-  g_return_if_fail(window != NULL);
-
-  match_data.function = TOKEN_D_CROSS;
-  match_data.detail = (gchar *)detail;
-  match_data.flags = THEME_MATCH_SHADOW | THEME_MATCH_STATE;
-  match_data.shadow = shadow;
-  match_data.state = state;
-  
-  if (!draw_simple_image (style, window, area, widget, &match_data, TRUE, TRUE,
-                         x, y, width, height))
-    parent_class->draw_cross (style, window, state, shadow, area, widget, detail,
-                             x, y, width, height);
-}
-
-static void
-draw_ramp (GtkStyle     *style,
-          GdkWindow    *window,
-          GtkStateType  state,
-          GtkShadowType shadow,
-          GdkRectangle *area,
-          GtkWidget    *widget,
-          const gchar  *detail,
-          GtkArrowType  arrow_direction,
-          gint          x,
-          gint          y,
-          gint          width,
-          gint          height)
-{
-  ThemeMatchData match_data;
-  
-  g_return_if_fail(style != NULL);
-  g_return_if_fail(window != NULL);
-
-  match_data.function = TOKEN_D_RAMP;
-  match_data.detail = (gchar *)detail;
-  match_data.flags = THEME_MATCH_SHADOW | THEME_MATCH_STATE;
-  match_data.shadow = shadow;
-  match_data.state = state;
-  
-  if (!draw_simple_image (style, window, area, widget, &match_data, TRUE, TRUE,
-                         x, y, width, height))
-    parent_class->draw_ramp (style, window, state, shadow, area, widget, detail,
-                            arrow_direction, x, y, width, height);
-}
-*/
-
 static void
 draw_tab (GtkStyle     *style,
          GdkWindow    *window,
@@ -1087,17 +1015,13 @@ pixbuf_style_class_init (PixbufStyleClass *klass)
   style_class->draw_hline = draw_hline;
   style_class->draw_vline = draw_vline;
   style_class->draw_shadow = draw_shadow;
-  style_class->draw_polygon = draw_polygon;
   style_class->draw_arrow = draw_arrow;
   style_class->draw_diamond = draw_diamond;
-  /*style_class->draw_oval = draw_oval;*/
   style_class->draw_string = draw_string;
   style_class->draw_box = draw_box;
   style_class->draw_flat_box = draw_flat_box;
   style_class->draw_check = draw_check;
   style_class->draw_option = draw_option;
-  /*style_class->draw_cross = draw_cross;*/
-  /*style_class->draw_ramp = draw_ramp;*/
   style_class->draw_tab = draw_tab;
   style_class->draw_shadow_gap = draw_shadow_gap;
   style_class->draw_box_gap = draw_box_gap;
index 210b0f5256c951a453a9ee67339262e37da8cb48..22f394145547e98eea6e21e4e2e623d67b80f63c 100644 (file)
@@ -87,6 +87,7 @@ theme_symbols[] =
   { "SLIDER",          TOKEN_D_SLIDER },
   { "ENTRY",           TOKEN_D_ENTRY },
   { "HANDLE",          TOKEN_D_HANDLE },
+  { "STEPPER",         TOKEN_D_STEPPER },
 
   { "TRUE",            TOKEN_TRUE },
   { "FALSE",           TOKEN_FALSE },
@@ -331,7 +332,7 @@ theme_parse_function(GScanner * scanner,
     return G_TOKEN_EQUAL_SIGN;
 
   token = g_scanner_get_next_token(scanner);
-  if ((token >= TOKEN_D_HLINE) && (token <= TOKEN_D_HANDLE))
+  if ((token >= TOKEN_D_HLINE) && (token <= TOKEN_D_STEPPER))
     data->match_data.function = token;
 
   return G_TOKEN_NONE;
index 2638fc87bd547171dfae6727110182adfa54301d..5d3b32e126d59323f6926f549f6b80f4ac14d702 100644 (file)
@@ -74,6 +74,7 @@ enum
   TOKEN_D_SLIDER,
   TOKEN_D_ENTRY,
   TOKEN_D_HANDLE,
+  TOKEN_D_STEPPER,
   TOKEN_TRUE,
   TOKEN_FALSE,
   TOKEN_TOP,